﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace iNet.Windows
{
	/// <summary>
	/// 提供 UIElement 相關的延伸功能。
	/// </summary>
	public static class UIElementExtensions
	{
		#region FadeIn
		/// <summary>
		/// 淡入指定的 UIElement。
		/// </summary>
		/// <param name="element">指定的 UIElement。</param>
		/// <param name="duration">淡入動畫的時間長度。</param>
		/// <param name="startVisibility">淡入前 UIElement 的可視性，Null (Visual Basic 為 Nothing) 表示維持原始的可視性。</param>
		/// <param name="endVisibility">淡入後 UIElement 的可視性，Null (Visual Basic 為 Nothing) 表示維持淡入前的可視性。</param>
		/// <returns>表示淡入動畫的 DoubleAnimation。</returns>
		/// <exception cref="ArgumentNullException">element 為 Null (Visual Basic 為 Nothing)。</exception>
		public static DoubleAnimation FadeIn(this UIElement element, TimeSpan duration, Visibility? startVisibility, Visibility? endVisibility)
		{
			return FadeIn(element, new Duration(duration), startVisibility, endVisibility);
		}
		/// <summary>
		/// 淡入指定的 UIElement。
		/// </summary>
		/// <param name="element">指定的 UIElement。</param>
		/// <param name="duration">淡入動畫的時間長度。</param>
		/// <param name="startVisibility">淡入前 UIElement 的可視性，Null (Visual Basic 為 Nothing) 表示維持原始的可視性。</param>
		/// <param name="endVisibility">淡入後 UIElement 的可視性，Null (Visual Basic 為 Nothing) 表示維持淡入前的可視性。</param>
		/// <returns>表示淡入動畫的 DoubleAnimation。</returns>
		/// <exception cref="ArgumentNullException">element 為 Null (Visual Basic 為 Nothing)。</exception>
		public static DoubleAnimation FadeIn(this UIElement element, Duration duration, Visibility? startVisibility, Visibility? endVisibility)
		{
			//確認參數
			if (element == null)
				throw new ArgumentNullException("element");

			//建立動畫
			DoubleAnimation animation = new DoubleAnimation(1, duration);

			//更新 Visibility
			if (startVisibility != null)
				element.Visibility = startVisibility.Value;
			if (endVisibility != null)
			{
				animation.Completed += (sender, e) =>
					{
						element.Visibility = endVisibility.Value;
					};
			}

			//淡出
			element.BeginAnimation(UIElement.OpacityProperty, animation);
			return animation;
		}
		#endregion
		#region FadeOut
		/// <summary>
		/// 淡出指定的 UIElement。
		/// </summary>
		/// <param name="element">指定的 UIElement。</param>
		/// <param name="duration">淡出動畫的時間長度。</param>
		/// <param name="startVisibility">淡出前 UIElement 的可視性，Null (Visual Basic 為 Nothing) 表示維持原始的可視性。</param>
		/// <param name="endVisibility">淡出後 UIElement 的可視性，Null (Visual Basic 為 Nothing) 表示維持淡出前的可視性。</param>
		/// <returns>表示淡出動畫的 DoubleAnimation。</returns>
		/// <exception cref="ArgumentNullException">element 為 Null (Visual Basic 為 Nothing)。</exception>
		public static DoubleAnimation FadeOut(this UIElement element, TimeSpan duration, Visibility? startVisibility, Visibility? endVisibility)
		{
			return FadeOut(element, new Duration(duration), startVisibility, endVisibility);
		}
		/// <summary>
		/// 淡出指定的 UIElement。
		/// </summary>
		/// <param name="element">指定的 UIElement。</param>
		/// <param name="duration">淡出動畫的時間長度。</param>
		/// <param name="startVisibility">淡出前 UIElement 的可視性，Null (Visual Basic 為 Nothing) 表示維持原始的可視性。</param>
		/// <param name="endVisibility">淡出後 UIElement 的可視性，Null (Visual Basic 為 Nothing) 表示維持淡出前的可視性。</param>
		/// <returns>表示淡出動畫的 DoubleAnimation。</returns>
		/// <exception cref="ArgumentNullException">element 為 Null (Visual Basic 為 Nothing)。</exception>
		public static DoubleAnimation FadeOut(this UIElement element, Duration duration, Visibility? startVisibility, Visibility? endVisibility)
		{
			//確認參數
			if (element == null)
				throw new ArgumentNullException("element");

			//建立動畫
			DoubleAnimation animation = new DoubleAnimation(0, duration);

			//更新 Visibility
			if (startVisibility != null)
				element.Visibility = startVisibility.Value;
			if (endVisibility != null)
			{
				animation.Completed += (sender, e) =>
				{
					element.Visibility = endVisibility.Value;
				};
			}

			//淡出
			element.BeginAnimation(UIElement.OpacityProperty, animation);
			return animation;
		}
		#endregion
	}
}
